package com.autumn.chat.core;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.autumn.chat.config.GlobalParam;
import com.autumn.chat.constant.BLiveOperationConstant;
import com.autumn.chat.http.DoBLiveApi;
import com.autumn.chat.socket.SSLWebSocketClient;
import com.autumn.chat.struct.blive.BLiveProto;
import com.autumn.chat.task.GPTMessageConsumeTask;
import com.autumn.chat.task.ProjectHearBeatTask;
import com.autumn.chat.task.WSSHeartBeatTask;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.enums.ReadyState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;

/**
 * ClassName: CoreService
 * Description:
 * Author: Shen_Yue
 * Date: 2023/3/4 1:58
 * History:
 * <author>          <time>          <version>          <desc>
 * wangqiuyang    2023/3/4 1:58   @Version 1.0        描述
 */
public class CoreService {

    private static final Logger log = LoggerFactory.getLogger(CoreService.class);

    /**
    * Description: 核心逻辑
    * @param
    * @return: void
    * @author: Shen_Yue
    * @Date: 1:59 2023/3/4
    */
    public void run() {

        // 初始化参数 等步骤
        init();

        // 项目开启 并且 发送心跳
        projectStartAndHeartBeat();

        // 建立长链接 并且 发送心跳
        createWebsocketAndHeartBeat();

        // 启动 gpt 推送线程
        gptBotMessagePushTaskStart();

        // 轮询 关闭直播间 防止主进程关闭
        close();
    }

    /**
    * Description: 本地 初始化
    * @param
    * @return: void
    * @author: Shen_Yue
    * @Date: 2:39 2023/3/4
    */
    private void init() {

        // 读取配置文件
        readConfig();
    }

    /**
    * Description: 读取配置文件的值
    * @param
    * @return: void
    * @author: Shen_Yue
    * @Date: 16:26 2023/3/4
    */
    private void readConfig() {

        Properties prop = new Properties();
        try (InputStream input = CoreService.class.getClassLoader().getResourceAsStream("config.properties")) {
            if (input == null) {
                throw new RuntimeException("无法找到配置文件");
            }
            prop.load(input);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 读取属性值
        String ACCESS_KEY_ID = prop.getProperty("ACCESS_KEY_ID");
        String ACCESS_KEY_SECRET = prop.getProperty("ACCESS_KEY_SECRET");
        String OPEN_AI_SECRET_KEY = prop.getProperty("OPEN_AI_SECRET_KEY");
        String APP_ID = prop.getProperty("APP_ID");
        String AUTH_ID = prop.getProperty("AUTH_ID");
        String PROXY_HOST = prop.getProperty("PROXY_HOST");
        String PROXY_PORT = prop.getProperty("PROXY_PORT");
        String MAX_TOKENS = prop.getProperty("MAX_TOKENS");

        // 全局变量赋值
        GlobalParam.ACCESS_KEY_ID = ACCESS_KEY_ID;
        GlobalParam.ACCESS_KEY_SECRET = ACCESS_KEY_SECRET;
        GlobalParam.OPEN_AI_SECRET_KEY = OPEN_AI_SECRET_KEY;
        GlobalParam.APP_ID = Long.parseLong(APP_ID);
        GlobalParam.AUTH_ID = AUTH_ID;
        GlobalParam.PROXY_HOST = PROXY_HOST;
        GlobalParam.PROXY_PORT = Integer.parseInt(PROXY_PORT);
        GlobalParam.MAX_TOKENS = Integer.parseInt(MAX_TOKENS);

    }

    /**
    * Description: 项目开启 并且 发送心跳
    * @param
    * @return: void
    * @author: Shen_Yue
    * @Date: 2:36 2023/3/4
    */
    private void projectStartAndHeartBeat() {
        // 1. 获取直播间信息
        String startBody = DoBLiveApi.getStart();
        log.info("/start返回值 : ---->  " + startBody);

        // 2. 整理获取的数据 准备建立连接的数据
        JSONObject json = JSONObject.parseObject(startBody);
        JSONObject data = json.getJSONObject("data");
        JSONObject websocketInfo = data.getJSONObject("websocket_info");
        // 长链接用的 authBody 和 wssLinks
        JSONObject authBody = websocketInfo.getJSONObject("auth_body");
        JSONArray wssLinks = websocketInfo.getJSONArray("wss_link");

        // 设置全局参数下文会用
        GlobalParam.WSS_LINK = wssLinks.getString(0);
        GlobalParam.AUTH_BODY = authBody.toString();
        GlobalParam.PROJECT_STARTED = true;

        // gameId 后面调用接口用
        String gameId = data.getJSONObject("game_info").getString("game_id");
        GlobalParam.GAME_ID = gameId;

        // 3. 建立发送心跳的任务
        ProjectHearBeatTask projectHeartBeatTask = new ProjectHearBeatTask();
        projectHeartBeatTask.setName("项目心跳线程");
        projectHeartBeatTask.start();
    }

    /**
    * Description: 建立长链接 并且 发送心跳
    * @param
    * @return: void
    * @author: Shen_Yue
    * @Date: 2:37 2023/3/4
    */
    private void createWebsocketAndHeartBeat() {
        // 1. 建立连接
        URI socketUrl = null;
        try {
            socketUrl = new URI(GlobalParam.WSS_LINK);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        SSLWebSocketClient sslWebSocketClient = new SSLWebSocketClient(socketUrl, new Draft_6455());
        sslWebSocketClient.connect();

        // 2. 判断是否连接成功
        int waitTime = 0;
        while(!sslWebSocketClient.getReadyState().equals(ReadyState.OPEN) && waitTime < 40) {
            log.info("目前还没有打开");
            try {
                Thread.sleep(500L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            waitTime ++;
        }
        if (waitTime > 40) {
            GlobalParam.PROJECT_STARTED = false;
            return;
        }

        // 设置全局参数
        GlobalParam.WSS_STARTED = true;
        GlobalParam.sslWebSocketClient = sslWebSocketClient;

        // 3. 发送鉴权信息
        // 组装包
        BLiveProto proto = new BLiveProto(BLiveOperationConstant.OP_AUTH , GlobalParam.AUTH_BODY);
        byte[] packProto = proto.pack();
        sslWebSocketClient.sendMsg(packProto);

        // 4. 建立心跳检测任务
        WSSHeartBeatTask heartBeatTask = new WSSHeartBeatTask();
        heartBeatTask.setName("WSS心跳线程");
        heartBeatTask.start();
    }

    /**
    * Description: 启动 gpt 推送
    * @param
    * @return: void
    * @author: Shen_Yue
    * @Date: 16:55 2023/3/4
    */
    private void gptBotMessagePushTaskStart() {
        GlobalParam.GPT_PUSH_STARTED = true;

        // 启动线程
        GPTMessageConsumeTask heartBeatTask = new GPTMessageConsumeTask();
        heartBeatTask.setName("GPT 推送线程");
        heartBeatTask.start();
    }

    /**
    * Description: 轮询等待关闭项目
    * @param
    * @return: void
    * @author: Shen_Yue
    * @Date: 2:38 2023/3/4
    */
    private void close() {
        do {
            try {
                // 5秒检测一次是否断开了连接或关闭了项目
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (GlobalParam.WSS_STARTED && GlobalParam.PROJECT_STARTED);

        log.info("连接断开了 关闭项目" );
        String end = DoBLiveApi.getEnd(GlobalParam.GAME_ID);
        log.info("end - > " + end );
    }
}
